﻿using System;
using System.Configuration;

namespace InfiniTec.Configuration
{
	public sealed class ConfigurationManager
	{
		private readonly System.Configuration.Configuration _Configuration;

		public ConfigurationManager()
		{
		}

		public ConfigurationManager(ConfigurationUserLevel userLevel)
		{
			_Configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(userLevel);
		}

		public ConfigurationManager(string configurationFile)
		{
			if (string.IsNullOrEmpty(configurationFile)) throw new ArgumentNullException("configurationFile");

			_Configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(
				new ExeConfigurationFileMap {ExeConfigFilename = configurationFile}, ConfigurationUserLevel.None);
		}

		public T GetSection<T>(string name)
			where T: ConfigurationSection
		{
			if (_Configuration != null)
			{
				return (T) _Configuration.GetSection(name);
			}
			return (T) System.Configuration.ConfigurationManager.GetSection(name);
		}

		public void Save()
		{
			EnsureConfigurationIsWritable();
			_Configuration.Save(ConfigurationSaveMode.Minimal);
		}

		public T CreateSection<T>(string name)
			where T : ConfigurationSection, new()
		{
			EnsureConfigurationIsWritable();
		    var section = new T();
    	    section.SectionInformation.AllowDefinition = ConfigurationAllowDefinition.MachineToApplication;
			_Configuration.Sections.Add(name, section);
			return section;
		}

		private void EnsureConfigurationIsWritable()
		{
			if (_Configuration == null) throw new NotSupportedException("The default configuration can not be modified.");
		}

		public string GetConnectionString(string connectionStringName)
		{
			if (string.IsNullOrEmpty(connectionStringName)) throw new ArgumentNullException("connectionStringName");
			var connectionStringSettings = _Configuration.ConnectionStrings.ConnectionStrings[connectionStringName];
			if (connectionStringSettings == null)
			{
				throw new ArgumentException(string.Format("A connectionstring with the name {0} could not be found.", connectionStringName), "connectionStringName");
			}
			return connectionStringSettings.ConnectionString;
		}
	}
}